﻿using System;
using System.Collections.Generic;
using CI.Misc;
using NUnit.Framework;
using CI.Interfaces;
using CI.Mesopotamia;
using CI.Organism;

namespace Mesopotamia.UnitTests
{
    [TestFixture]
    public class SurvivalFattestTests
    {

        private IHostingEnvironment _msrbhost;
        private IFitnessFunction _fitnessFunction;
        private readonly SurvivalFattest _survivalFattest = new SurvivalFattest();

        /// <summary>
        /// setup
        /// </summary>
        [SetUp]
        public void Setup()
        {
            _msrbhost = new MSRBHost(new MockHostingEnvironmentPhysical(), new ScenarioLocalXML());
            _fitnessFunction = new CollisionDetection();
        }

        /// <summary>
        /// Make sure it blows up on null hosting environment
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "hostingEnvironment")]
        public void RestrictionCheckingNullHostingEnvironmentException()
        {
            _survivalFattest.RestrictionChecking(null);
        }

        /// <summary>
        /// Make sure it blows up on null hosting environment
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "organism")]
        public void FitnessCheckingNullOrganismException()
        {
            _survivalFattest.FitnessChecking(null);
        }

        /// <summary>
        /// Make sure it blows up on null organisms
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "organisms")]
        public void TrimInactiveNullOrganismException()
        {
            SimpleSimulationRestrictions.TrimInactive(null, 0, _fitnessFunction);
        }

        /// <summary>
        /// Make sure it blows up on null hosting environment
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "fitnessFunction")]
        public void TrimInactiveNullIFitnessFunctionException()
        {
            SimpleSimulationRestrictions.TrimInactive(new List<IOrganism>(), 0, null);
        }

        [Test]
        public void TrimInactiveInGreaterOutLess()
        {
            const int topCount = 1;
            var organisms = new List<IOrganism>
                                {
                                    new CI.Organism.Organism(_msrbhost, Guid.NewGuid(), 0, 0),
                                    new CI.Organism.Organism(_msrbhost, Guid.NewGuid(), 0, 0)
                                };
            var result = SimpleSimulationRestrictions.TrimInactive(organisms, topCount, _fitnessFunction);
            Assert.AreEqual(topCount, result.Count, "Count of returned organisms is not correct");
        }

        /// <summary>
        /// make sure it picks up the null hosting environment
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "hostingEnvironment")]
        public void CheckInactiveCountNullhostingEnvironment()
        {
            _survivalFattest.CheckInactiveCount(null);
        }


        /// <summary>
        /// call check inactive count and make sure we got back how many we expected
        /// </summary>
        [Test]
        public void CheckInactiveInOutCount()
        {
            for (int i = 0; i < 50; i++)
            {
                _msrbhost.Organisms.InactiveAdd(new CI.Organism.Organism(_msrbhost, Guid.NewGuid(), 0, 0));
            }

            _msrbhost.FitnessFunction = _fitnessFunction;

            _survivalFattest.CheckInactiveCount(_msrbhost);

            // currently the _inactiveKeep is 10 so check against that
            Assert.AreEqual(10, _msrbhost.Organisms.Inactive.Count, "inactive count not what it should be");

        }
    }
}
